前面都只有介紹一個 Container 服務一個 Port 那大家是不是有一個疑問如果我的 Container 是多個 Port 的服務有沒有辦法用 ECS 嗎?答案是可以的呦!平常看到的範例都是多個 Port 就要開多個 Container 那我可以節省成本只用一個 Container 就好嗎?答案也是可以的呦!
今天就來教大家怎麼達成這件事情吧!
因為要測試多 Port 服務所以我寫了一個測試程式提供給大家測試,它可以顯示目前連線的網址與 Port
這支程式開的 Port 為:80、8080、8000 與 8888
我們這次的 Task 與之前差不多,主要的重點是這次我們宣告了多個 container port
const taskDefinition = new ecs.FargateTaskDefinition(this, "TaskDef", {
memoryLimitMiB: 512,
cpu: 256,
});
const container = taskDefinition.addContainer("container", {
image: ecs.ContainerImage.fromDockerImageAsset(asset),
memoryLimitMiB: 512,
});
container.addPortMappings(
{
containerPort: 80,
},
{
containerPort: 8888,
},
{
containerPort: 8080,
},
{
containerPort: 8000,
}
);
如此在 Task Definition 就可以看到我們宣告的 Port Mappings 表
我們在 ALB 上面 Listen 剛剛的 80、8080、8000 與 8888
這邊有一個新的設定是 defaultAction
我們希望他在沒有 Rules 的時候做什麼事情,在後面我特別保留了 8888 port 沒有設定,這樣就可以看到它是什麼樣子了!
要注意這個值一定要設定不然會有問題呦!
const lb = new elbv2.ApplicationLoadBalancer(this, "LB", {
vpc,
internetFacing: true,
});
const listener1 = lb.addListener("Listener1", {
port: 80,
defaultAction: elbv2.ListenerAction.fixedResponse(200, {
contentType: elbv2.ContentType.TEXT_PLAIN,
messageBody: "OK",
}),
});
const listener2 = lb.addListener("Listener2", {
port: 8080,
defaultAction: elbv2.ListenerAction.fixedResponse(200, {
contentType: elbv2.ContentType.TEXT_PLAIN,
messageBody: "OK",
}),
});
const listener3 = lb.addListener("Listener3", {
port: 8888,
protocol: elbv2.ApplicationProtocol.HTTP,
defaultAction: elbv2.ListenerAction.fixedResponse(200, {
contentType: elbv2.ContentType.TEXT_PLAIN,
messageBody: "OK",
}),
});
const listener4 = lb.addListener("Listener4", {
port: 8000,
defaultAction: elbv2.ListenerAction.fixedResponse(200, {
contentType: elbv2.ContentType.TEXT_PLAIN,
messageBody: "OK",
}),
});
我們分別把 Container 的 port 都跟 Listener 對應保留剛剛說的 8888 沒有設定對應
這邊有一個重點是 containerName
一定要與建立 Fargate Task Definition時設定的一樣,因為他們是靠同一個名稱做連結的
listener1.addTargets("ECS1", {
port: 80,
targets: [
service.loadBalancerTarget({
containerName: "container",
containerPort: 80,
}),
],
});
listener2.addTargets("ECS2", {
port: 8080,
targets: [
service.loadBalancerTarget({
containerName: "container",
containerPort: 8080,
}),
],
});
listener4.addTargets("ECS4", {
port: 8000,
protocol: elbv2.ApplicationProtocol.HTTP,
targets: [
service.loadBalancerTarget({
containerName: "container",
containerPort: 8000,
}),
],
});
由上面三張圖我們可以觀察到,我們的 ECS Container 都是同一台
我們可以回到 ECS 的 Service 看一下我們只有一個 Service,而且只有一個 Running 的 Task
再到 ECS Task 確定只有一個 Task 在跑
我們可以到 ALB 的網址 http://cdkec-lb8a1-iyxzyuebmegp-816266764.us-west-2.elb.amazonaws.com:80/ 看到服務正常並且有讀到 Port
ALB 的網址 http://cdkec-lb8a1-iyxzyuebmegp-816266764.us-west-2.elb.amazonaws.com:8080/ 看到服務正常並且有讀到 Port
ALB 的網址 http://cdkec-lb8a1-iyxzyuebmegp-816266764.us-west-2.elb.amazonaws.com:8000/ 也是一樣的情況
ALB 的網址 http://cdkec-lb8a1-iyxzyuebmegp-816266764.us-west-2.elb.amazonaws.com:8888/ 因為我們剛剛做了一點手腳所以只有回應 Default 的 OK
今天是測試如果一台機器需要服務多個 Port 的範例希望有幫助到大家!
文章內容主要是網路或是程式開發類型的文章
本文同步刊載於 Clarence 部落格:Day 24 - CDK 建置 Amazon Elastic Container Service(ECS) Service - 一個 Container 服務多個 Port
「AWS CDK 完全學習手冊:打造雲端基礎架構程式碼 IaC」
本書改編並延伸自第 12 屆 iT 邦幫忙鐵人賽獲得 DevOps 組冠軍的《用 CDK 定義 AWS 架構》系列文章,以簡單、好讀的行文風格詳述技術細節,並提供完整的程式碼範例與說明,一步一步帶領新手從零開始踏上 AWS CDK 技術達人之路。有興趣的朋友歡迎至天瓏書局選購!